package com.yu.crm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yu.crm.domain.pojo.ProSoftFile;
import com.yu.crm.domain.pojo.ProSoftware;
import com.yu.crm.domain.request.FileRequest;
import com.yu.crm.domain.response.ProSoftwareRep;
import com.yu.crm.mapper.ProSoftwareMapper;
import com.yu.crm.service.IProSoftwareService;
import com.yxzz.common.helper.ExceptionHelpers;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 软件表 服务实现类
 * </p>
 *
 * @author zds
 * @since 2021-04-02
 */
@Slf4j
@Service
public class ProSoftwareService extends ServiceImpl<ProSoftwareMapper, ProSoftware> implements IProSoftwareService {

    @Value("${upload.basedir}")
    private String basedir;

    @Autowired
    private ProSoftFileService fileService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void upload(FileRequest fileRequest) {
        try {
            MultipartFile[] files = fileRequest.getFolder();
            //当前软件版本根目录
            String rootDir = basedir + fileRequest.getAppId();
            ProSoftware proSoftware = new ProSoftware();
            proSoftware.setName(fileRequest.getName());
            proSoftware.setAppId(fileRequest.getAppId());
            proSoftware.setVersion(fileRequest.getVersion());
            proSoftware.setRootDir(rootDir);
            //判断是否第一次上传
            ProSoftware software = getOneByAppId(fileRequest.getAppId());
            Long softId = null;
            if (software != null) {
                softId = software.getId();
                if (!files[0].isEmpty()) {
                    fileService.deleteBySoftwareId(software.getId());
                }
            }
            baseMapper.saveOrUpdate(proSoftware);
            if (softId == null) {
                softId = proSoftware.getId();
            }
            List<ProSoftFile> list = new ArrayList<>(files.length);
            boolean flag = true;
            for (MultipartFile multipartFile : files) {
                if (multipartFile.isEmpty()) {
                    break;
                }
                if (flag) {
                    //当前版本有上传过则删除文件
                    File rootFile = new File(rootDir);
                    if (rootFile.exists()) {
                        deleteFile(rootFile);
                    }
                    flag = false;
                }
                String fileName = multipartFile.getOriginalFilename();
                //获取系统文件分隔符
                String separator = System.getProperty("file.separator");
                //文件全路径
                String filePath = rootDir + separator + fileName;
                File file = new File(filePath);
                //文件夹不存在则创建
                if (!file.getParentFile().exists()) {
                    file.getParentFile().mkdirs();
                }
                //保存本地文件
                multipartFile.transferTo(file);
                ProSoftFile softFile = new ProSoftFile();
                softFile.setFileName(fileName);
                softFile.setSoftId(softId);
                list.add(softFile);
            }
            fileService.saveBatch(list);
        } catch (IOException e) {
            log.error("文件上传失败:{}", e);
            ExceptionHelpers.throwGeneralException("文件上传失败!");
        }
    }

    private ProSoftware getOneByAppId(String appId) {
        QueryWrapper<ProSoftware> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_deleted", 0);
        queryWrapper.eq("app_id", appId);
        return baseMapper.selectOne(queryWrapper);
    }

    public ProSoftwareRep getVersion(String appId) {
        ProSoftware software = baseMapper.getByAppId(appId);
        ProSoftwareRep rep = new ProSoftwareRep();
        rep.setAppId(software.getAppId());
        rep.setRootDir(software.getRootDir());
        rep.setVersion(software.getVersion());
        List<String> files = software.getFiles()
                .stream()
                .map(ProSoftFile::getFileName)
                .collect(Collectors.toList());
        rep.setFiles(files);
        return rep;
    }

    public IPage<ProSoftware> getPage(Page<ProSoftware> page, String condition) {
        QueryWrapper<ProSoftware> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_deleted", 0);
        if (StringUtils.isNotBlank(condition)) {
            queryWrapper.and(i -> i.like("app_id", condition)
            );
        }
        return baseMapper.selectPage(page, queryWrapper);
    }

    private static void deleteFile(File file) {
        File[] files = file.listFiles();
        //如果包含文件进行删除操作
        if (ArrayUtils.isNotEmpty(files)) {
            for (File file1 : files) {
                if (file1.isFile()) {
                    //删除子文件
                    file1.delete();
                } else if (file1.isDirectory()) {
                    //通过递归的方法找到子目录的文件
                    deleteFile(file1);
                }
            }
        }
        file.delete();
    }
}
